-
Notifications
You must be signed in to change notification settings - Fork 8
feat: Full abstraction of note-cpp from note-arduino
#83
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
note-cpp from note-arduino
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand the primary motivation is to abstract the communication and debug streams.
I'd like to summarize the current pattern with NoteLog since NoteSerial follows the same pattern, and begin and setDebugOutputStream also follow a similar pattern, so I'll choose setDebugOutputStream.
Calling Notecard::setDebugOutputStream() follows these steps
-
The caller passes the arduino
Streamto the call. The type isNoteLog::channel_twhich isvoid* -
Inside the notecard implementation
make_note_logis called, which takes thevoid*to the stream and creates aNoteLog_Arduinoinstance, which requires aStream*- thevoid*stream is statically cast toStream*. -
NoteLogis a polymorphic interface, with a virtual methodprint.
The main concerns here is that it isn't type-safe, and there's a tight coupling between the caller and the make_note_log implementation. But thanks to the NoteLog interface, this can be easily fixed in a type-safe way and without the tight coupling. We can also still maintain the singleton instance required too.
#ifdef ARDUINO
// Arduino-specific override
void setDebugOutput(Stream* stream) {
setDebugOutput(new NoteLog_Arduino(stream));
}
#endif
void setDebugOutput(NoteLog* log) {
// set the global instance
note_log = log;
}
private:
static NoteLog* note_log;
Then when we want to implement this for a different streaming platform, e.g. C stdio, then we can just create a new NoteLog subclass
class NoteLog_stdio : public NoteLog {
OStream* stream;
void print(const char* c) {
stream->write(c);
}
}
And use that as the debug stream
notecard.setDebugOutput(new NoteLog_stdio(&cout));
This lets the caller choose what type of stream they want, rather than it being fixed by make_note_log and type-safety is provided.
To sum up - the key change is to pass around NoteLog instances rather than the implementation specific NoteLog::channel_t which is merely a catch-all type.
The type safety is the real problem. The |
This simple abstraction fully isolates the Arduino
Streamobject, and demonstrates the path to abstraction for bothSerialandI2C.